package model;

import manager.IAnalizadorSintactico;
import manager.IToken;
import manager.ITokenStream;

public class Factor1  extends AbstractAnalizadorSintactico implements IAnalizadorSintactico {
	
	/* INICIALIZACION */	
	public Factor1 ( ITokenStream ts ) {
		super(ts, false);
	}
	public Factor1 ( ITokenStream ts, boolean debugMode ) {
		super(ts,debugMode);
	}
	
	
	/** 
	 * Devuelve true si reconoce que se completa una llamada a una funcion, un arreglo o una variable
	 */
	public boolean reconocer () {

		boolean recognized = true; //(asumimos correctitud hasta demostrar lo contrario)

		//----------------------------------------------
		//Agrego info de debug de la produccion
		em.debug( "Reconocer Factor1:");		//TODO pasarlo a accion semantica
		//----------------------------------------------
		
		/* <FACTOR_1> -> ( <FACTOR_2> ) |
             			 [ <EXP> ] 		|
             			 LAMBDA 		*/

		if ( this.getTokenSiguiente().equals( new Token(IToken.TYPE_PARENTESIS_IZQ)) ) {
			
			// <FACTOR_1> -> ( <FACTOR_2> )
			
			//----------------------------------------------
			//Agrego info de debug de la produccion
			em.debug( "<FACTOR_1> -> ( <FACTOR_2> )", this.getTokenSiguiente() );
			//----------------------------------------------
			
			// Reconocer Parentesis Izq
			if ( !this.reconocerToken(IToken.TYPE_PARENTESIS_IZQ) ) {
				//El reconocerToken() habria adelantado el tokenStream hasta salir de esta iteracion,
				//entonces no hay que seguir buscando sino salir
				return false;
			}
			
			// Reconocer Factor2
			IAnalizadorSintactico factor2 = new Factor2(this.tokenStream,this.debugMode);
			recognized &= factor2.reconocer();
			
			// Reconocer Parentesis Der
			if ( !this.reconocerToken(IToken.TYPE_PARENTESIS_DER) ) {
				return false;
			}
			
		} else if ( this.getTokenSiguiente().equals( new Token(IToken.TYPE_CORCHETE_IZQ)) ) {
			
			// <FACTOR_1> -> [ <EXP> ] )
			
			//----------------------------------------------
			//Agrego info de debug de la produccion
			em.debug( "<FACTOR_1> -> [ <EXP> ]", this.getTokenSiguiente() );
			//----------------------------------------------
			
			// Reconocer Parentesis Izq
			if ( !this.reconocerToken(IToken.TYPE_CORCHETE_IZQ) ) {
				return false;
			}
			
			// Reconocer Expresion
			IAnalizadorSintactico expresion = new Expresion(this.tokenStream,this.debugMode);
			recognized &= expresion.reconocer();
			
			// Reconocer Parentesis Der
			if ( !this.reconocerToken(IToken.TYPE_CORCHETE_DER) ) {
				return false;
			}
		}
		return recognized;
	}
	
	public static boolean primeros(IToken token) {
		return  token.equals( new Token(IToken.TYPE_PARENTESIS_IZQ) ) ||
				token.equals( new Token(IToken.TYPE_CORCHETE_IZQ) );
	}
}

